import { redux, utils } from '@ohif/core';
import store from './../../store';

const commandsModule = ({ commandsManager }) => {
  const { setViewportActive, setActiveViewportSpecificData, changeViewMode, setLayout, setImageLayout, setSidePanels } = redux.actions;

  const actions = {
    showHideStudiesPanel: ({ preferences }) => {
      const p = preferences.sidePanels['study-browser'] || { pos: 'auto', show: false };
      store.dispatch(setSidePanels({ 'study-browser': { ...p, show: !p.show } }));
    },
    setStudiesPanelPos: ({ pos }) => {
      store.dispatch(setSidePanels({ 'study-browser': { pos, show: true } }));
    },
    setSeriesLayout: ({ viewports, numRows, numColumns }) => {
      const modeViewports = viewports[viewports.viewMode];
      const currentLayout = modeViewports.layout;
      const activeViewportIndex = modeViewports.activeViewportIndex;
      const numViewports = numRows * numColumns;
      const vps = [];
      for (let i = 0; i < numViewports; ++i) {
        const vp = currentLayout.viewports[i];
        vps.push({ ...vp });
      }

      store.dispatch(changeViewMode('normal'));
      const maxActiveIndex = numViewports - 1;
      if (activeViewportIndex > maxActiveIndex) {
        store.dispatch(setViewportActive(0));
      }

      store.dispatch(setLayout({
        numRows,
        numColumns,
        viewports: vps,
      }));
    },
    setImageLayout: ({ viewports, numRows, numColumns }) => {
      const modeViewports = viewports[viewports.viewMode] || {};
      const vp = modeViewports.layout.viewports[modeViewports.activeViewportIndex];
      const { activeViewportIndex = 0 } = vp;
      store.dispatch(setImageLayout({
        numRows,
        numColumns,
        activeViewportIndex: (activeViewportIndex > numRows * numColumns -1) ? 0 : activeViewportIndex,
      }));
    },
    updateActiveViewport: ({ viewports, direction }) => {
      const modeViewports = viewports[viewports.viewMode];
      const { viewportSpecificData, activeViewportIndex } = modeViewports;
      const maxIndex = Object.keys(viewportSpecificData).length - 1;

      let newIndex = activeViewportIndex + direction;
      newIndex = newIndex > maxIndex ? 0 : newIndex;
      newIndex = newIndex < 0 ? maxIndex : newIndex;

      store.dispatch(setViewportActive(newIndex));
    },
    setWindowLevelPreset: ({ viewports, preset }) => {
      const state = store.getState();
      const { preferences: { wlPresets = [] } } = state;
      const { window, level } = wlPresets.find(p => p.id == preset);

      if (window && level) {
        commandsManager.runCommand('setWindowLevel', {
          viewports,
          window,
          level,
        });
      }
    },
    updateViewportDisplaySet: ({ viewports, direction }) => {
      const modeViewports = viewports[viewports.viewMode];
      const viewportSpecificData = { ...modeViewports.viewportSpecificData };
      const activeViewport =
        viewportSpecificData[modeViewports.activeViewportIndex];
      const studyMetadata = utils.studyMetadataManager.get(
        activeViewport.StudyInstanceUID
      );

      if (!studyMetadata) {
        return;
      }

      const allDisplaySets = studyMetadata.getDisplaySets();
      const currentDisplaySetIndex = allDisplaySets.findIndex(
        displaySet =>
          displaySet.displaySetInstanceUID ===
          activeViewport.displaySetInstanceUID
      );
      if (currentDisplaySetIndex < 0) {
        return;
      }

      const newDisplaySetIndex = currentDisplaySetIndex + direction;
      const newDisplaySetData = allDisplaySets[newDisplaySetIndex];
      if (!newDisplaySetData) {
        return;
      }

      store.dispatch(setActiveViewportSpecificData(newDisplaySetData));
    },
  };

  const definitions = {
    showHideStudiesPanel: {
      commandFn: actions.showHideStudiesPanel,
      storeContexts: ['preferences'],
    },
    setStudiesPanelPos: {
      commandFn: actions.setStudiesPanelPos,
    },
    setSeriesLayout: {
      commandFn: actions.setSeriesLayout,
      storeContexts: ['viewports'],
    },
    setImageLayout: {
      commandFn: actions.setImageLayout,
      storeContexts: ['viewports'],
    },
    // Next/Previous active viewport
    incrementActiveViewport: {
      commandFn: actions.updateActiveViewport,
      storeContexts: ['viewports'],
      options: { direction: 1 },
    },
    decrementActiveViewport: {
      commandFn: actions.updateActiveViewport,
      storeContexts: ['viewports'],
      options: { direction: -1 },
    },
    // Window level Presets
    windowLevelPreset1: {
      commandFn: actions.setWindowLevelPreset,
      storeContexts: ['viewports'],
      options: { preset: 1 },
    },
    windowLevelPreset2: {
      commandFn: actions.setWindowLevelPreset,
      storeContexts: ['viewports'],
      options: { preset: 2 },
    },
    windowLevelPreset3: {
      commandFn: actions.setWindowLevelPreset,
      storeContexts: ['viewports'],
      options: { preset: 3 },
    },
    windowLevelPreset4: {
      commandFn: actions.setWindowLevelPreset,
      storeContexts: ['viewports'],
      options: { preset: 4 },
    },
    windowLevelPreset5: {
      commandFn: actions.setWindowLevelPreset,
      storeContexts: ['viewports'],
      options: { preset: 5 },
    },
    windowLevelPreset6: {
      commandFn: actions.setWindowLevelPreset,
      storeContexts: ['viewports'],
      options: { preset: 6 },
    },
    windowLevelPreset7: {
      commandFn: actions.setWindowLevelPreset,
      storeContexts: ['viewports'],
      options: { preset: 7 },
    },
    windowLevelPreset8: {
      commandFn: actions.setWindowLevelPreset,
      storeContexts: ['viewports'],
      options: { preset: 8 },
    },
    windowLevelPreset9: {
      commandFn: actions.setWindowLevelPreset,
      storeContexts: ['viewports'],
      options: { preset: 9 },
    },
    nextViewportDisplaySet: {
      commandFn: actions.updateViewportDisplaySet,
      storeContexts: ['viewports'],
      options: { direction: 1 },
    },
    previousViewportDisplaySet: {
      commandFn: actions.updateViewportDisplaySet,
      storeContexts: ['viewports'],
      options: { direction: -1 },
    },
  };

  return {
    definitions,
    defaultContext: 'VIEWER',
  };
};

export default commandsModule;
